#ifndef INTERP_LIST_HH
#define INTERP_LIST_HH

#include <vector>
#include <nmlmsg.hh>
#include <stdint.h>
#include "rs274ngc/interp_base.hh"
#include <memory>
#include <set>
#include <map>
#include <atomic>
#include <string>

#define MAX_NML_COMMAND_SIZE 1000

// these go on the interp list
struct NML_INTERP_LIST_NODE
{
    int line_number;  // line number it was on
    union _dummy_union
    {
        int32_t i;
        int32_t l;
        double d;
        float f;
        int64_t ll;
        long double ld;
    } dummy;  // paranoid alignment variable.

    union _command_union
    {
        char commandbuf[MAX_NML_COMMAND_SIZE];  // the NML command;
        int32_t i;
        int32_t l;
        double d;
        float f;
        int64_t ll;
        long double ld;
    } command;
};

// here's the interp list itself
class NML_INTERP_LIST
{
public:
    NML_INTERP_LIST();
    ~NML_INTERP_LIST();

    int set_line_number(int line);
    int get_line_number();
    int append(NMLmsg&);
    int append(NMLmsg*);
    NMLmsg* get();
    void clear();
    void print();
    int len();

private:
    class LinkedList* linked_list_ptr;
    NML_INTERP_LIST_NODE temp_node;  // filled in and put on the list
    int next_line_number;            // line number used to fill temp_node
    int line_number;                 // line number of node from get()
};

typedef struct
{
    int zucAuxInputWaitDIType;
    int zucAuxInputWaitIndex;
    int zucAuxInputWaitType;
    double taskExecDelayTimeout;
    bool waiting;
} AuxInputWaitMsg;
typedef struct
{
    int thread_id;
    pthread_t pth_t;
    std::shared_ptr<InterpBase> threadInterp;
    std::unique_ptr<NML_INTERP_LIST> nmlcmd_list;
    AuxInputWaitMsg auxInputWaitMsg;
    int new_flag;
    std::string thread_alias;
    int destroy_flag = 0;
    int pause_flag = 0;
    int join_flag = 0;
    int is_mutex = 0;
    int is_running = 0;
    int destroied_flag = 0;
} ThreadInterpInfo;

#define MAX_SUB_THREAD 5

extern NML_INTERP_LIST interp_list; /* NML Union, for interpreter */

extern int waitFlag;

extern bool waitTimeout;

extern int threadInterpNum;

extern ThreadInterpInfo threadInterpList[MAX_SUB_THREAD];

extern pthread_mutex_t cmd_chn_lock;  // 锁以及状态

extern pthread_mutexattr_t cmd_chn_lock_attr;

extern std::set<std::map<pthread_t, std::string>> threadStatusList;

extern pthread_cond_t thread_cond;

extern pthread_mutex_t glb_resources_lock;  // 锁以及状态

extern std::atomic_bool thread_pause_flag;
extern std::atomic_bool thread_exit_flag;
extern std::atomic_bool multi_thread_flag;
#endif
